// Copyright (c) 2025, 大连理工大学 (Dalian University of Technology)
//
// Licensed under the Mulan PSL v2.
// You can use this file according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of the License at
//
//     http://license.coscl.org.cn/MulanPSL2
//
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. SEE THE MULAN PSL v2
// FOR MORE DETAILS.

/*
 * @Author: qiulin_JXGM ql1746365080@gmail.com
 * @Date: 2024-10-16 09:35:57
 * @LastEditors: qiulin 1746365080@qq.com
 * @LastEditTime: 2025-01-02 17:23:20
 * @FilePath: \SGFEM\Import\BDFImport\BulkData\Property\PBEAMParser.cpp
 */
#include "PBRSECTParser.h"

#include <algorithm>
#include <cstdint>

#include <boost/algorithm/string.hpp>

#include "Utility/Logging/SGLogger.h"

#include "DBManager/DBServiceFactory.h"
#include "DBManager/IService/Input/Node/IPointService.h"
#include "DBManager/IService/Input/Property/IPBRSECTService.h"
#include "DBManager/IService/Input/Partition/ISET1Service.h"

#include "Import/BDFImport/BDFParserBase.h"

BULKDATA_ENTRY_PARSER_REG (PBRSECT);

using namespace SG::DBManager;
using namespace SG::Import;
using namespace SG::Import::BDF;
using namespace SG::DataStructure;
using SG::DataStructure::Common::Status;

/*
// file://./../../Doc/MarkDown/BulkData/PBEAM/PBEAM.md>
*/
enum PBRSECTKey : std::uint8_t
{
    PBRSECTKey_ID   = 1,
    PBRSECTKey_MID  = 2,
    PBRSECTKey_FORM = 3,
};

Status BDF::BULKDATA::ParsePBRSECT (const std::shared_ptr<SG::DBManager::DBServiceFactory>& dbServiceFactory,
                                    std::vector<std::string>&                               dividedEntryInfo)
{
    // 创建临时数据对象以存储解析结果
    SG::DataStructure::FEM::PBRSECTData tempData;

    // TODO(bug 001) 需要正确填写m_domainId
    tempData.m_domainId = 1;

    tempData.m_id  = convertToI64 (dividedEntryInfo[PBRSECTKey_ID]);
    tempData.m_MID = convertToI64 (dividedEntryInfo[PBRSECTKey_MID]);
    boost::trim (dividedEntryInfo[PBRSECTKey_FORM]);
    
    if(dividedEntryInfo[PBRSECTKey_FORM] == "GS")
    {
        tempData.m_FORM = 1;
    }
    else if(dividedEntryInfo[PBRSECTKey_FORM] == "OP")
    {
        tempData.m_FORM = 2;
    }
    else if(dividedEntryInfo[PBRSECTKey_FORM] == "CP")
    {
        tempData.m_FORM = 3;
    }

    SG::DataStructure::FEM::PBRSECTData::section sect;
    int rowCount = dividedEntryInfo.size () / 10;
    for (int r = 1; r < rowCount; r++)
    {
        for (int c = 0; c < 10; c++)
        {
            int         pos    = r * 10 + c;
            std::string curKey = dividedEntryInfo[pos];
            if (is_all_space (curKey))
            {
                continue;
            }
            std::vector<std::string> result;
            boost::split (result, curKey, boost::is_any_of ("="));
            if (result.front () == "OUTP")
            {
                tempData.m_OUTP = convertToI64 (result.back ());
            }
            else if (result[0] == "INP")
            {
                sect.inps.push_back ({ 0, convertToI64 (result.back ()) });
            }
            else if (result[0] == "ING")
            {
                sect.ings.push_back ({ 0, convertToI64 (result.back ()) });
            }
            else
            {
                SGWarn << curKey << " Temporarily not supported";
            }
        }
    }

    SG::DataStructure::FEM::SET1Data sd;
    if(dbServiceFactory->get<ISET1Service> ()->FindById(tempData.m_OUTP, sd) == SG::DataStructure::Common::Status::STATUS_Failure)
    {
        SGError << "Failed to obtain SET data";
        return Status::STATUS_Failure;
    }
        

    sect.OHEIGHT = dbServiceFactory->get<IPointService> ()->GetOverallHeighth (sd.m_gids);
    sect.OWIDTH  = dbServiceFactory->get<IPointService> ()->GetOverallWidth (sd.m_gids);

    tempData.m_sections.push_back (sect);

    return dbServiceFactory->get<IPBRSECTService> ()->Add (tempData);
}